#include <jni.h>
#include <android/log.h>
#include <stdlib.h>
#include <assert.h>
#include "physic.h"

#ifndef NELEM
#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0])))
#endif

#define LOG_TAG "Physic-jni"
#define LOG_LEVEL 10
#define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);}
#define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);}

static int register_native_methods(JNIEnv *env, const char *clsName, JNINativeMethod *methods, int numOfMethod){
	jclass cls;
	cls = (*env)->FindClass(env, clsName);

	if(cls == NULL){
		LOGE(1, "Native tester unable to find class '%s' \n", clsName);
		return JNI_FALSE;
	}

	if( (*env)->RegisterNatives(env, cls, methods, numOfMethod) <0 ){
		LOGE(1, "NativeTester Register Failed \n");
		return JNI_FALSE;
	}

	return JNI_TRUE;
}

/**
 * JNI Callback function
 * */
jint JNICALL JNI_OnLoad(JavaVM *vm, void* reserved){
	JNIEnv *env;
	jint result = -1;

	if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK){
		LOGE(3, "ERROR: Get env failed \n");
		goto bail;
	}
	assert(env != NULL);

	if( register_native_methods(env, FunctionClassPath, physic_methods, NELEM(physic_methods)) < 0 ){
		LOGE(3, "ERROR: Register methods failed \n");
		goto bail;
	}

	result = JNI_VERSION_1_6;

bail:
	return result;
}

/*
void JNI_OnUnload(JavaVM *vm, void *reserved){
}
*/
